package proyecto.testcasetool.presentation.details.scenario;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.observable.list.ComputedList;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.databinding.edit.EMFEditObservables;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewerSupport;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import proyecto.testcasetool.TestcasetoolPackage;
import proyecto.testcasetool.UseCase;
import proyecto.testcasetool.UseCaseModel;



public class ActionStepDetailPage extends AbstractStepsDetailPage {
	

	private ComboViewer comboViewerAgent;
	private AdapterFactoryItemDelegator afid;
	
	public ActionStepDetailPage(FormToolkit toolkit, EditingDomain editingDomain,
			AdapterFactory adapterFactory) {
		super(toolkit, editingDomain, adapterFactory);
		afid =  new AdapterFactoryItemDelegator(adapterFactory);
	}

	@Override
	protected void createDetailsSection(Composite parent) {

		super.createDetailsSection(parent);
		
		Control[] controls = parent.getChildren();
		Section section = (Section) controls[0];
		Composite client = (Composite) section.getClient();
		
		createAgentCombo(client);
		
	}

	
	private void createAgentCombo(Composite client) {
		Label lblAlternative = toolkit.createLabel(client, "Agent", SWT.NONE);
		GridData gdLabelAlternative = new GridData();
		gdLabelAlternative.verticalIndent = 10;
		lblAlternative.setLayoutData(gdLabelAlternative);
		
		final CCombo c = new CCombo(client, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER);
		comboViewerAgent = new ComboViewer((CCombo)c);
		comboViewerAgent.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));
		
		comboViewerAgent.setContentProvider(new ObservableListContentProvider());
		
		GridData gdCombo = new GridData();
		gdCombo.verticalIndent = 10;
		gdCombo.widthHint = 200;
		c.setLayoutData(gdCombo);

	}
	
	public void selectionChanged(IFormPart part, ISelection selection) {
		if (!(selection instanceof IStructuredSelection)) {
			return;
		}
		EObject newEObject = getEObjectFromSelection(selection);
		if (newEObject != null && newEObject != eObject) {
			eObject = newEObject;
			if (eObject != null) {
				
				IObservableValue obsDescFeature = EMFEditObservables
						.observeValue(editingDomain, eObject,
								TestcasetoolPackage.Literals.STEP__DESCRIPTION);

				
				bindingContext.bindValue(SWTObservables.observeText(
						txtDescription, SWT.FocusOut), obsDescFeature);

				// pre state
				
				IObservableValue obsPreStateFeature = EMFEditObservables
						.observeValue(editingDomain, eObject,
								TestcasetoolPackage.Literals.ACTION_STEP__PRESTATE);

				
				bindingContext.bindValue(SWTObservables.observeText(
						txtPreState, SWT.FocusOut), obsPreStateFeature);
				
				// post state
				
				IObservableValue obsPostStateFeature = EMFEditObservables
						.observeValue(editingDomain, eObject,
								TestcasetoolPackage.Literals.ACTION_STEP__POSTSTATE);

				
				bindingContext.bindValue(SWTObservables.observeText(
						txtPostState, SWT.FocusOut), obsPostStateFeature);
				
				//
				
				IObservableValue obsNameFeature = EMFEditObservables
						.observeValue(editingDomain, eObject,
								TestcasetoolPackage.Literals.STEP__NAME);

				bindingContext.bindValue(
						SWTObservables.observeDelayedValue(400, SWTObservables
								.observeText(txtStepName, SWT.Modify)),
						obsNameFeature);
				
				IObservableValue obsIdFeature = EMFEditObservables
						.observeValue(editingDomain, eObject,
								TestcasetoolPackage.Literals.STEP__ID);

				bindingContext.bindValue(
						SWTObservables.observeDelayedValue(400, SWTObservables
								.observeText(txtStepId, SWT.Modify)),
						obsIdFeature);
				
				
				
				obsManager.addObservable(obsNameFeature);
				obsManager.addObservable(obsDescFeature);
				obsManager.addObservable(obsIdFeature);
				obsManager.addObservable(obsPostStateFeature);
				obsManager.addObservable(obsPreStateFeature);
				
				bindActorsSection();
			}
			
		}
		else{

		}
	}


	private void bindActorsSection(){
	
		
		Object parent = afid.getParent(afid.getParent(eObject));
		
		if (!(parent instanceof UseCase)){
			parent = afid.getParent(parent);
		}

		final UseCase useCase = (UseCase) parent;
		final UseCaseModel useCaseModel = (UseCaseModel) afid.getParent(afid.getParent(useCase));
		
		ComputedList list = new ComputedList() {
			
			IObservableValue obsSubject = EMFEditObservables.observeValue(editingDomain,useCaseModel, TestcasetoolPackage.Literals.USE_CASE_MODEL__SUBJECT);
			IObservableList participantActorsList = EMFEditObservables.observeList(editingDomain,useCase, TestcasetoolPackage.Literals.USE_CASE__PARTICIPANT_ACTOR);
			
			@Override
			protected List calculate() {
				@SuppressWarnings("rawtypes")
				ArrayList l = new ArrayList (); 
				l.add(obsSubject.getValue());
				l.addAll(participantActorsList); 
				return l; 
			}
			
		};
		
		IValueProperty labelProperty = EMFEditProperties.value(editingDomain, TestcasetoolPackage.Literals.AGENT__NAME);
		
        ViewerSupport.bind(comboViewerAgent, list, labelProperty);
        
        IObservableValue comboSelectionValue = ViewersObservables.observeSingleSelection(comboViewerAgent);
        IObservableValue emfValue = EMFEditObservables.observeValue(editingDomain,eObject, TestcasetoolPackage.Literals.ACTION_STEP__AGENT);
        
        bindingContext.bindValue(comboSelectionValue, emfValue);
        
        obsManager.addObservable(comboSelectionValue);
        obsManager.addObservable(emfValue);

	}
	
	
	@Override
	public void dispose() {
		super.dispose();
	}
	

}